<?php

namespace helper\util;

class File
{
    /**
     * 保存数组变量到php文件
     * @param string $path 保存路径
     * @param mixed  $var  要保存的变量
     * @return boolean 保存成功返回true,否则false
     */
    function save_var($path, $var)
    {
        return file_put_contents($path, "<?php\treturn " . var_export($var, true) . ";?>");
    }

    /**
     * 读取php文件中配置
     * @param string $filename 保存路径
     * @return array
     */
    function read_var($filename)
    {
        if (is_file($filename . '.php')) {
            return include $filename . '.php';
        }
        return [];
    }

    /**
     * 配置文件
     */
    function config($file, $arr = [])
    {
        if (!$arr) {
            file_put_contents($file, serialize($arr));//写入数组序列化缓存
        } else {
            return unserialize(file_get_contents($file));//读取数组序列化缓存数据
        }
    }

    /**
     * 获取文件目录列表
     * @param string $pathname 路径
     * @param integer $fileFlag 文件列表 0所有文件列表,1只读文件夹,2是只读文件(不包含文件夹)
     * @param string $pattern
     * @return array
     */
    function get_file_folder_List($pathname,$fileFlag = 0, $pattern='*') {
        $fileArray = array();
        $pathname = rtrim($pathname,'/') . '/';
        $list   =   glob($pathname.$pattern);
        foreach ($list  as $i => $file) {
            switch ($fileFlag) {
                case 0:
                    $fileArray[]=basename($file);
                    break;
                case 1:
                    if (is_dir($file)) {
                        $fileArray[]=basename($file);
                    }
                    break;

                case 2:
                    if (is_file($file)) {
                        $fileArray[]=basename($file);
                    }
                    break;

                default:
                    break;
            }
        }

        if(empty($fileArray)) $fileArray = NULL;
        return $fileArray;
    }


    function size($filename)
    {
        return filesize($filename);
    }

    /**
     * @param int $size
     * @return string
     */
    public static function formatBytes(int $size): string
    {
        $base     = log($size, 1024);
        $suffixes = array('', 'KB', 'MB', 'GB', 'TB');
        return round(pow(1024, $base - floor($base)), 2) . ' ' . $suffixes[floor($base)];
    }

    /**
     * PHP格式化字节大小
     * @param  number $size      字节数
     * @param  string $delimiter 数字和单位分隔符
     * @return string            格式化后的带单位的大小
     */
    function format_bytess($size, $delimiter = ''): string
    {
        $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
        for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
        return round($size, 2) . $delimiter . $units[$i];
    }

    /**
     * 获取目录里的文件，不包括下级文件夹
     * @param string $dir  路径
     * @return array
     */
    function get_dir($dir){
        $file = @ scandir($dir);
        foreach ($file as $key){
            if ( $key != ".." && $key != "." ){
                $files[] = $key;
            }
        }
        return $files;
    }

    /**
     * 获取文件夹中的文件,含目录
     * @param $path
     * @param string $exts
     * @param array $list
     * @return array
     */
    function dir_list($path, $exts = '', $list= array()) {
        $path = dir_path($path);
        $files = glob($path.'*');
        foreach ($files as $v) {
            $fileext = fileext($v);
            if (!$exts || preg_match("/\.($exts)/i", $v)) {
                $list[] = $v;
                if (is_dir($v)) {
                    $list = dir_list($v, $exts, $list);
                }
            }
        }
        return $list;
    }

    /**
     * 补齐目录后的/
     * @param $path string 目录
     * @return string
     */
    function dir_path($path) {
        $path = str_replace('\\', '/', $path);
        if (substr($path, -1) != '/') $path = $path.'/';
        return $path;
    }

    /**
     * 查找文件后缀
     * @param $filename string 文件名称
     * @return string 后缀名称（如：html）
     */
    function ext(string $filename) {
        return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));
    }

    /**
     * 删除目录及文件
     * @param $dir
     * @return bool
     */
    function dir_delete($dir) {
        $dir = dir_path($dir);
        if (!is_dir($dir)) return FALSE;
        $list = glob($dir.'*');
        foreach ($list as $v) {
            is_dir($v) ? dir_delete($v) : @unlink($v);
        }
        return @rmdir($dir);
    }

    /**
     * 对网络图片内容进行Base64编码
     * @param string $path
     * @return string
     */
    public function base64Img(string $path): string
    {
        //对path进行判断，如果是本地文件就二进制读取并base64编码，如果是url,则返回
        $img_data = "";
        if (substr($path, 0, strlen("http")) === "http") {
            $img_data = $path;
        } else {
            if ($fp = fopen($path, "rb", 0)) {
                $binary = fread($fp, filesize($path)); // 文件读取
                fclose($fp);
                $img_data = base64_encode($binary); // 转码
            }
            //chunk_split(base64_encode(file_get_contents($path)))
        }
        return $img_data;
    }

    /**
     * 下载文件
     * @param  [type] $url  [description]
     * @param  [type] $path [description]
     * @return void
     */
    function down($url, $path)
    {
        $arr = parse_url($url);
        $fileName = basename($arr['path']);
        $file = file_get_contents($url);
        //数据写入文件
        $fh = fopen($path . $fileName, 'wb');
        fwrite($fh, $file);
        fclose($fh);
    }

    /**
     * 压缩文件
     * @param array $files 待压缩文件 array('d:/test/1.txt'，'d:/test/2.jpg');【文件地址为绝对路径】
     * @param string $filePath 输出文件路径 【绝对文件地址】 如 d:/test/new.zip
     * @return string|bool
     */
    function zip($files, $filePath)
    {
        //检查参数
        if (empty($files) || empty($filePath)) {
            return false;
        }
        //PHP自带的扩展类
        $zip = new ZipArchive();
        $zip->open($filePath, ZipArchive::CREATE);
        foreach ($files as $key => $file) {
            //检查文件是否存在
            if (!file_exists($file)) {
                return false;
            }
            $zip->addFile($file, basename($file));
        }
        $zip->close();
        return true;
    }

    /**
     * zip解压方法
     * @param string $filePath 压缩包所在地址 【绝对文件地址】d:/test/123.zip
     * @param string $path 解压路径 【绝对文件目录路径】d:/test
     * @return bool
     */
    function unzip($filePath, $path)
    {
        if (empty($path) || empty($filePath)) {
            return false;
        }
        //PHP自带的扩展类
        $zip = new ZipArchive();
        if ($zip->open($filePath) === true) {
            $zip->extractTo($path);
            $zip->close();
            return true;
        } else {
            return false;
        }
    }

    /**
     * 记录日志
     * @param mixed $msg 消息内容
     * @param string $type 消息类型 debug, info, notice, warning, error, critical, alert, emergency
     * @param int $mode 写入方式 0:file_put_contents(),1:fwrite(),2:error_log()
     * @return boolean
     */
    function write($msg, $type = 'info', $mode = 0)
    {
        $dir = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR;
        $path = $dir . date('Ym') . DIRECTORY_SEPARATOR;
        $filename = $path . DIRECTORY_SEPARATOR . date('d') . '.log';

        // 创建目录
        if (!is_dir($path)) {
            mkdir($path, 0755, true);
        }

        // 写入内容
        $msg = is_string($msg) ? $msg : var_export($msg, true);
        $string = '[' . date('c') . '][' . $type . '] ' . $msg . "\r\n";

        // 写入方式
        if ($mode == 0) {
            file_put_contents($filename, $string, FILE_APPEND | LOCK_EX);
        } elseif ($mode == 1) {
            $fp = fopen($filename, 'a');
            if (flock($fp, LOCK_EX)) {// 进行排它型锁定 并发
                ftruncate($fp, 0);// truncate file
                fwrite($fp, $string);
                fflush($fp);// flush output before releasing the lock
                flock($fp, LOCK_UN);// 释放锁定
            }
            fclose($fp);
        } else {
            error_log($string, 3, $filename);
        }
        return true;
    }
}